﻿using Ldt.DataEngine.DataFlowParse.Model;
using Ldt.DataEngine.RuleAssemble;
using Ldt.InformationUnit.Common;
using LdtDataEngin.ModuleDetail.AnalysisModule.CaseCauseElementExtr;
using LdtDataEngin.ModuleDetail.BaseModule;
using LdtJudge.DataEngine.CallInterface.ConfiCenter;
using LdtJudge.DataEngine.Common;
using LdtJudge.DataEngine.Common.ConfigXmlLoad;
using LdtJudge.DataEngine.Common.XmlUtility;
using LdtJudge.DataEngine.DataBaseStores;
using LdtJudge.DataEngine.Model.DataModel.SysCommon;
using LdtJudge.DataEngine.Model.ElmentModel;
using LdtJudge.DataEngine.Model.Personnel;
using LdtJudge.DataEngine.Model.XMLConfigModel.SameNodeConfigModel;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Xml;

namespace LdtDataEngin.ModuleDetail.CaseCauseElementExtr
{
    public class CaseCauseElementExtraction: FactElementBaseClass
    {
        #region 属性添加
        /// <summary>
        /// 证据要素
        /// </summary>
        private List<NodeModel> EvidInfo;

        /// <summary>
        /// 事实要素
        /// </summary>
        private List<NodeModel> FactElement;

        /// <summary>
        /// XML抽取实体对象
        /// </summary>
        private ModelToXml modelToXml = new ModelToXml();

        /// <summary>
        /// 诉请要素
        /// </summary>
        private List<NodeModel> SuitInfo;
            
        public string moudleName;
        #endregion

        /// <summary>
        /// 要素提取，分析转xml对象
        /// </summary>
        /// <param name="onExtract"></param>
        /// <param name="nodeModelList"></param>
        /// <returns></returns>
        public override XmlNode ExtElementXmlParse(OnExtractComplete onExtract, NodeModelList nodeModelList)
        {
            if (!_dataContext.DataLayerAns.IsParagraphAnalysis.HasValue || _dataContext.DataLayerAns.IsParagraphAnalysis == false)
            {
                List<string> listvalue = RuleParseClass.GetParseRegCodeList("TextType", _dataContext.DataLayerAns.FengXiCanShu.Juanzongneirong);
                if (listvalue.Count > 0 && _dataContext.DataLayerAns.SourceCode.ToLower() == "mssuitbook")
                {
                    _dataContext.DataLayerAns.TextType = listvalue[0];
                }
            }
            //加载分人员数据
            base.GroupParseTextDic = base.GetGroupParseText(_dataContext.DataLayerAns.Fayanrenduanluoxinxis);//dynamicDataStores.dataLayerStores.SpokeTextDialogue);
            
            ///base.GroupParseTextDic = base.GroupParseTextDic.Where(a => a.Key.SuitDegreeID != "t2").ToDictionary(a => a.Key, b => b.Value);
            //人员内容分组，集合内容
            var groupnamelist = base.GroupParseTextDic.GroupBy(ke => new { ke.Key.SP_Name, ke.Key.SuitDegreeID }).
                Select(g => new { entity = new { name = g.Key.SP_Name, SuitId = g.Key.SuitDegreeID }, list = g.ToDictionary(a => a.Key, b => b.Value) });

            //分人员提取完毕的集合内容
            // 案由对应的人员提取集合
            Dictionary<string, List<NodeModelList>> caseCauseValueParirsList = new Dictionary<string, List<NodeModelList>>();
            
            if (_dataContext.DataLayerAns.CaseCausesList.Count > 0)
            {
                var configModel = _dataContext.DataLayerSys.GetConfigModel(moudleName);
                ConfigModel amountConfig = new ConfigModel();
                if (configModel!=null && configModel.ConfigDetail!=null)
                {
                    amountConfig = configModel.ConfigDetail.FirstOrDefault(a => a.Code.ToLower() == "amountconversion");
                    if(amountConfig!=null)
                        _dataContext.InteractiveShow.LogShow($"执行模块编号:{"amountconversion"} 执行code:{amountConfig.ExecuteCode} 文件路径:{amountConfig.FilePath}", LogMessageType.Info);

                }
                foreach (CaseCauseModel casecause in _dataContext.DataLayerAns.CaseCausesList)
                {
                    List<NodeModelList> valuePairsList = new List<NodeModelList>();
                    //获取cofig信息内容
                    Dictionary<string, ElementConfigModel> diccofig = GetElementConfig(casecause.CC_ID);
                    //查询事实要素的提取合并配置（用证据代替）
                    OptimizeSourceSerializable optimizeSource = new OptimizeSourceSerializable();
                    /* 案由要素分析中需要用到优选的同节点判定  需要与业务(王巧凤)确认将同节点判定拆分出来 */
                    var sameNodeConfig = GetSameNodeConfig();
                    var elementMLConfigContent = GetFactElemnetMlConfig(configModel, casecause.CC_ID);
                    if (sameNodeConfig != null && sameNodeConfig.xmllable!=null && sameNodeConfig.xmllable.Length>0)
                    {
                        List<SameNodeXml> sameNodeList = sameNodeConfig.xmllable.ToList();
                        //获取当前案由下的所有要素节点配置
                        List<CaseCauseModel> listMsysCase = GetMSYS_CaseCausesList(casecause.CC_ID).ToList();
                        //加载分人员下的数据
                        foreach (var diclist in groupnamelist)
                        {
                            Dictionary<PersonElementEntity, string> dicgrouplist = diclist.list;
                            CaseCauseModel caseCauseModel = listMsysCase.FirstOrDefault(a => a.CC_ParentID == casecause.CC_ID && a.CC_Name== "案由要素");
                            if(caseCauseModel!=null)
                            {
                                foreach (CaseCauseModel casecmode in listMsysCase.Where(child => child.CC_ParentID == caseCauseModel.CC_ID))
                                {
                                    CaseCauseModel casec = new CaseCauseModel();
                                    casec = JsonConvert.DeserializeObject<CaseCauseModel>(JsonConvert.SerializeObject(casecmode));
                                    casec.CC_ParentID = casecause.CC_ID;
                                    //判断调用并执行线程
                                    switch (casec.CC_Name)
                                    {
                                        case "诉请要素":
                                            try
                                            {
                                                Stopwatch swtext = new Stopwatch();
                                                swtext.Start();
                                                SuitInfoElement suitInfoElement = new SuitInfoElement
                                                {
                                                    spokenamelist = spokenamelist,
                                                    casecauseList = listMsysCase,
                                                    SYS_CaseCause = casecause,
                                                    mSYS_CaseCause = casec,
                                                    _dataContext = _dataContext,
                                                    CaseID = base.CaseID,
                                                    GroupParseTextDic = dicgrouplist,
                                                    causeSys = casecause,
                                                    Diccofig = diccofig,
                                                    suitinfocode = suitinfocode,
                                                    suitin = suitin
                                                };
                                                NodeModelList nodeModelListsuit = new NodeModelList();
                                                nodeModelListsuit.NodeModelKey = new NodeModelKey() { SP_Name = diclist.entity.name, SP_SuitdegreeID = diclist.entity.SuitId, ElementType = ElementTypes.诉请要素, CauseID = casecause.CC_ID };
                                                nodeModelListsuit.AfterMergeXmlNode = suitInfoElement.ExtElementXmlParse(single_OnComplete, nodeModelListsuit);
                                                valuePairsList.Add(nodeModelListsuit);
                                                swtext.Stop();
                                                _dataContext.InteractiveShow.LogShow("诉请要素提取时间" + swtext.Elapsed.TotalMilliseconds.ToString());
                                            }
                                            catch (Exception ex)
                                            {
                                                _dataContext.InteractiveShow.LogShow("诉请要素提取错误-" + ex.ToString(), LogMessageType.Error);
                                            }
                                            break;
                                        case "事实要素":
                                            try
                                            {
                                                Stopwatch swtext = new Stopwatch();
                                                swtext.Start();
                                                if (diclist.entity.SuitId == "t2")
                                                {
                                                    #region 提取审理人员无争议事实要素内容
                                                    ///进行无争议要素提取
                                                    List<NodeModel> NoArgumentList = new List<NodeModel>();
                                                    NoArgumentElement NoArgumentInfoElement = new NoArgumentElement
                                                    {
                                                        spokenamelist = spokenamelist,
                                                        casecauseList = listMsysCase,
                                                        _dataContext = _dataContext,
                                                        SYS_CaseCause = casecause,
                                                        mSYS_CaseCause = casec,
                                                        CaseID = base.CaseID,
                                                        causeSys = casecause,
                                                        GroupParseTextDic = dicgrouplist,
                                                        Diccofig = diccofig,
                                                        opconfigList = sameNodeList,
                                                        suitinfocode = suitinfocode,
                                                        suitin = suitin
                                                    };

                                                    NodeModelList nodeModelListNo = new NodeModelList();
                                                    nodeModelListNo.NodeModelKey = new NodeModelKey() { SP_Name = diclist.entity.name, SP_SuitdegreeID = diclist.entity.SuitId, ElementType = ElementTypes.无争议要素, CauseID = casecause.CC_ID };
                                                    nodeModelListNo.AfterMergeXmlNode = NoArgumentInfoElement.ExtElementXmlParse(single_OnComplete, nodeModelListNo);
                                                    #endregion
                                                    valuePairsList.Add(nodeModelListNo);
                                                }
                                                else
                                                {
                                                    #region  非审理人员的的事实要素
                                                    FactInfoElement FactElementM = new FactInfoElement
                                                    {
                                                        spokenamelist = spokenamelist,
                                                        casecauseList = listMsysCase,
                                                        _dataContext = _dataContext,
                                                        mSYS_CaseCause = casec,
                                                        SYS_CaseCause = casecause,
                                                        CaseID = base.CaseID,
                                                        GroupParseTextDic = dicgrouplist,
                                                        causeSys = casecause,
                                                        Diccofig = diccofig,
                                                        opconfigList = sameNodeList,
                                                        suitinfocode = suitinfocode,
                                                        suitin = suitin,
                                                        FactNodelMLConfig = elementMLConfigContent
                                                    };
                                                    NodeModelList nodeModelListFact = new NodeModelList();
                                                    nodeModelListFact.NodeModelKey = new NodeModelKey() { SP_Name = diclist.entity.name, SP_SuitdegreeID = diclist.entity.SuitId, ElementType = ElementTypes.事实要素, CauseID = casecause.CC_ID };
                                                    //生成后的节点信息
                                                    nodeModelListFact.AfterMergeXmlNode = FactElementM.ExtElementXmlParse(single_OnComplete, nodeModelListFact);
                                                    valuePairsList.Add(nodeModelListFact);
                                                    #endregion

                                                    #region  当前人员的证据提取
                                                    Stopwatch swtexts = new Stopwatch();
                                                    swtexts.Start();
                                                    EvidInfoElement evidInfoElement = new EvidInfoElement
                                                    {
                                                        spokenamelist = spokenamelist,
                                                        casecauseList = listMsysCase,
                                                        _dataContext = _dataContext,
                                                        SYS_CaseCause = casecause,
                                                        GroupParseTextDic = dicgrouplist,
                                                        mSYS_CaseCause = casec,
                                                        CaseID = base.CaseID,
                                                        causeSys = casecause,
                                                        Diccofig = diccofig,
                                                        suitinfocode = suitinfocode,
                                                        suitin = suitin,
                                                        FactNodelMLConfig= elementMLConfigContent
                                                    };
                                                    NodeModelList nodeModelListEvid = new NodeModelList();
                                                    nodeModelListEvid.NodeModelKey = new NodeModelKey() { SP_Name = diclist.entity.name, SP_SuitdegreeID = diclist.entity.SuitId, ElementType = ElementTypes.证据要素, CauseID = casecause.CC_ID};
                                                    nodeModelListEvid.AfterMergeXmlNode = evidInfoElement.ExtElementXmlParse(single_OnComplete, nodeModelListEvid);
                                                    valuePairsList.Add(nodeModelListEvid);
                                                    swtexts.Stop();
                                                    #endregion

                                                    _dataContext.InteractiveShow.LogShow("证据要素提取时间" + swtexts.Elapsed.TotalMilliseconds.ToString());
                                                }

                                                swtext.Stop();
                                                _dataContext.InteractiveShow.LogShow("事实要素提取时间" + swtext.Elapsed.TotalMilliseconds.ToString());
                                            }
                                            catch (Exception ex)
                                            {
                                                _dataContext.InteractiveShow.LogShow("事实要素提取错误-" + ex.ToString(), LogMessageType.Error);
                                            }
                                            break;
                                        case "结果要素":
                                            try
                                            {
                                                if (resultPersonnelList.Contains(diclist.entity.SuitId))
                                                {
                                                    Stopwatch swtext = new Stopwatch();
                                                    swtext.Start();
                                                    ResultInfoElement resultInfoElement = new ResultInfoElement
                                                    {
                                                        spokenamelist = spokenamelist,
                                                        casecauseList = listMsysCase,
                                                        SYS_CaseCause = casecause,
                                                        mSYS_CaseCause = casec,
                                                        _dataContext = _dataContext,
                                                        CaseID = base.CaseID,
                                                        GroupParseTextDic = dicgrouplist,
                                                        causeSys = casecause,
                                                        Diccofig = diccofig,
                                                        suitinfocode = suitinfocode,
                                                        suitin = suitin,
                                                        resultParagraphList = resultParagraphList,
                                                        resultPersonnelList = resultPersonnelList

                                                    };
                                                    NodeModelList nodeModelListsuit = new NodeModelList();
                                                    nodeModelListsuit.NodeModelKey = new NodeModelKey() { SP_Name = diclist.entity.name, SP_SuitdegreeID = diclist.entity.SuitId, ElementType = ElementTypes.结果要素, CauseID = casecause.CC_ID };
                                                    nodeModelListsuit.AfterMergeXmlNode = resultInfoElement.ExtElementXmlParse(single_OnComplete, nodeModelListsuit);
                                                    valuePairsList.Add(nodeModelListsuit);
                                                    swtext.Stop();
                                                    _dataContext.InteractiveShow.LogShow("结果要素提取时间" + swtext.Elapsed.TotalMilliseconds.ToString());
                                                }

                                            }
                                            catch (Exception ex)
                                            {
                                                _dataContext.InteractiveShow.LogShow("结果要素提取错误-" + ex.ToString(), LogMessageType.Error);
                                            }
                                            break;
                                        default:
                                            break;
                                    }
                                }
                            }
                            
                        }
                        caseCauseValueParirsList.Add(casecause.CC_ID, valuePairsList);
                    }
                    AnalysisElementSave_new(valuePairsList, amountConfig, casecause);
                }
                _dataContext.DataLayerAns.CaseCauseElementList=caseCauseValueParirsList;
            }
            else
            {
                //不存在
                _dataContext.InteractiveShow.LogShow("案由为空，不进行案由要素提取！！");
            }
            return null;
        }

        #region 要素提取结果内容输出

        /// <summary>
        /// 要素节点提取完毕内容输出
        /// </summary>
        /// <param name="extype">用途</param>
        /// <param name="NodeList">及时提取对象</param>
        /// <param name="ListMessage">消息结合</param>
        /// <param name="Person">人员对象</param>
        public void single_OnComplete(ExtractType extype, List<NodeModel> NodeList, IList<string> ListMessage, PersonElementEntity Person)
        {
            ModelToXml modelToXml = new ModelToXml();
            if (extype == ExtractType.evid)
            {
                ///证据要素提取
                //ExtEvidUnion(NodeList, Person);
            }
            else
            {///诉请或者事实
                if (Person.SuitDegreeID == "90" || Person.SuitDegreeID == "173")
                {
                    _dataContext.InteractiveShow.LogShow("****************被告" + Person.SP_Name + "的要素提取完毕*********" + Person.ParagraphCode + "*******");
                }
                else if (Person.SuitDegreeID == "89" || Person.SuitDegreeID == "174")
                {
                    _dataContext.InteractiveShow.LogShow("****************原告" + Person.SP_Name + "的要素提取完毕*********" + Person.ParagraphCode + "*******");
                }
                string xml = modelToXml.BuildXml(NodeList, _dataContext.DataLayerAns.CaseCausesList[0]);
                _dataContext.InteractiveShow.LogShow(xml);
            }

        }

        #endregion

        private SameNodeConfig GetSameNodeConfig()
        {
            var configModel = _dataContext.DataLayerSys.GetConfigModel(moudleName);
            SameNodeConfig sameNodeConfig = new SameNodeConfig();
            if (_dataContext.DataLayerAns.CaseCausesList.Count > 0)
            {
                if (!string.IsNullOrWhiteSpace(configModel.ConfigContent))
                {
                    XmlDocument xmlDocument = new XmlDocument();
                    xmlDocument.LoadXml(configModel.ConfigContent);
                    XmlNode xmlNode = xmlDocument.SelectSingleNode("/root/step[@code='samenodejudge']");
                    if (xmlNode != null)
                    {
                        Dictionary<string, string> dicElement = new Dictionary<string, string>();
                        string url = xmlNode.Attributes["executefile"].Value;
                        url = url.Replace("{casetype}", _dataContext.DataLayerAns.CaseType).Replace("{causecode}", _dataContext.DataLayerAns.CaseCausesList[0].CC_ID);
                        dicElement.Add("fileFullName", url);
                        string elementMessage = WebUtil.DoGet(ConfigRetrieval.GetConfigRetrieval.GetAppSettingString("systemapi") + "/api/WordParse/GetConfigFileContent", dicElement, "utf-8");
                        dynamic elementcofig = JsonConvert.DeserializeObject<dynamic>(elementMessage);
                        if (elementcofig.result.code.ToString() == "1")
                        {
                            string elementcofigstr = elementcofig.body;
                            sameNodeConfig = XmlUtility.DeserializeToObject<SameNodeConfig>(elementcofigstr);
                        }
                    }

                }
            }
            return sameNodeConfig;
        }

        /// <summary>
        /// 获取事实要素节点机器学习配置
        /// </summary>
        /// <returns></returns>
        private string GetFactElemnetMlConfig(ConfigModel configModel, string causeId)
        {
            string configContent = string.Empty;
            if (!string.IsNullOrWhiteSpace(configModel.ConfigContent))
            {
                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.LoadXml(configModel.ConfigContent);
                XmlNode xmlNode = xmlDocument.SelectSingleNode("/root/step[@code='elementmachlearn']");
                if (xmlNode != null)
                {
                    Dictionary<string, string> dicElement = new Dictionary<string, string>();
                    string url = xmlNode.Attributes["executefile"].Value;
                    url = url.Replace("{casetype}", _dataContext.DataLayerAns.CaseType).Replace("{causecode}", causeId);
                    dicElement.Add("fileFullName", url);
                    string elementMessage = WebUtil.DoGet(ConfigRetrieval.GetConfigRetrieval.GetAppSettingString("systemapi") + "/api/WordParse/GetConfigFileContent", dicElement, "utf-8");
                    dynamic elementcofig = JsonConvert.DeserializeObject<dynamic>(elementMessage);
                    if (elementcofig.result.code.ToString() == "1")
                        configContent = elementcofig.body;
                }
            }
            return configContent;
        }
    }
}
